﻿//-----------------------------------------------------------------------
// <copyright>
//     Copyright (c) Artur Mustafin. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Expressions.Compiler.Internal
{

    /// <summary>
    /// A stream position class
    /// </summary>
    internal sealed class Position<T>
    {
        private int _position;
        private Position<T> _next;
        private Reader<T> _reader;
        private T _value;

        /// <summary>
        /// Initializes a new instance of the <see cref="Position&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="position">The position.</param>
        /// <param name="reader">The reader.</param>
        internal Position(int position, Reader<T> reader)
        {
            _position = position;
            _reader = reader;
            _reader.Read();
            _value = _reader.Value;
        }

        /// <summary>
        /// Gets a value indicating whether this instance can read.
        /// </summary>
        /// <value><c>true</c> if this instance can read; otherwise, <c>false</c>.</value>
        internal bool CanRead { get { return !object.Equals(_value, Terminal<T>.Default); } }

        /// <summary>
        /// Gets the current.
        /// </summary>
        /// <value>The current.</value>
        internal T Value { get { return _value; } }

        /// <summary>
        /// Reads this instance.
        /// </summary>
        /// <returns>The input stream</returns>
        internal Position<T> Read()
        {
            if (_next == null)
            {
                _next = new Position<T>(_position + 1, _reader);
            }
            return _next;
        }

#if TRACE
        public override string ToString()
        {
            return _value.ToString();
        }
#endif
    }

    /// <summary>
    /// A stream position class
    /// </summary>
    internal sealed class Position
    {
        private int _position;
        private Position _next;
        private Reader _reader;
        private char _ch;

        /// <summary>
        /// Initializes a new instance of the <see cref="Position"/> class.
        /// </summary>
        /// <param name="position">The position.</param>
        /// <param name="reader">The reader.</param>
        internal Position(int position, Reader reader)
        {
            _position = position;
            _reader = reader;
            _reader.Read();
            _ch = _reader.Value;
        }

        /// <summary>
        /// Gets a value indicating whether this instance can read.
        /// </summary>
        /// <value><c>true</c> if this instance can read; otherwise, <c>false</c>.</value>
        internal bool CanRead { get { return _ch != Terminal.Null; } }

        /// <summary>
        /// Gets the current.
        /// </summary>
        /// <value>The current.</value>
        internal char Char { get { return _ch; } }

        /// <summary>
        /// Reads this instance.
        /// </summary>
        /// <returns>The input stream</returns>
        internal Position Read()
        {
            if (_next == null)
            {
                _next = new Position(_position + 1, _reader);
            }
            return _next;
        }

#if TRACE
        public override string ToString()
        {
            return _ch.ToString();
        }
#endif
    }
}
